package edu.neumont.MillerK.Android;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

public class LocationService extends Service{
	private Handler handler;
	private SharedPreferences sharedPrefs;
	private LocationManager locationManager;
	private LocationListener locationListener;
	private Location lastKnownLocation;
	private String emailUsername;
	private String password;
	private String longitude;
	private String latitude;
	private String altitude;
	private String time;
	private SimpleDateFormat simpleDateFormat;
	private boolean done = false;
	
	private Thread locationServletThread;
	
	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}
	
	@Override
	public void onCreate() {
		sharedPrefs = getSharedPreferences("default", MODE_PRIVATE);
		simpleDateFormat = new SimpleDateFormat("HH:mm:ss - dd/MM/yyyy");
		
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
		locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
		locationListener = new LocationListener() {
			
			public void onStatusChanged(String provider, int status, Bundle extras) {}
			
			public void onProviderEnabled(String provider) {}
			
			public void onProviderDisabled(String provider) {}
			
			public void onLocationChanged(Location location) {
				setLocationProperties(location);
				Log.d("LocationService", "Location Updated");
			}
		};
		
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 45000, 0, locationListener);
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 45000, 0, locationListener);
		handler = new Handler(){
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				requestForLocationServlet();
			}
		};
		emailUsername = sharedPrefs.getString("username", null);
		password = sharedPrefs.getString("password", null);
		
		requestForLocationServlet();
		
		Toast.makeText(LocationService.this, "LocationService Started", Toast.LENGTH_LONG).show();
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);
		locationServletThread.run();
		return START_STICKY;
	}
	
	private void requestForLocationServlet(){
		locationServletThread = new Thread(new Runnable() {
			public void run(){
				do{
					try {
				        // Create params for connection including 3sec timeout
				        // on connection and 5sec timeout on socket
				        HttpParams httpParams = new BasicHttpParams();
				        int timeoutConnection = 3000;
				        int timeoutSocket = 5000;
				 
				        // Set the timeouts
				        HttpConnectionParams.setConnectionTimeout(httpParams,
				                timeoutConnection);
				        HttpConnectionParams.setSoTimeout(httpParams, timeoutSocket);
				        HttpClient httpClient = new DefaultHttpClient(httpParams);
				        
				        Log.d("LocationService", "Running!");
				 
				        // Create the data entities
				        HttpPost post = new HttpPost("http://b3rwyn.dyndns-free.com:8080/MillerK_Capstone_Web-Service/AndroidLocations");
				        HttpResponse response;
				 
				        // Set POST data
				        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
				                2);
				        nameValuePairs.add(new BasicNameValuePair("emailUsername",
				                emailUsername));
				        nameValuePairs.add(new BasicNameValuePair("password",
				                password));
				        nameValuePairs.add(new BasicNameValuePair("longitude",
				        		longitude));
				        nameValuePairs.add(new BasicNameValuePair("latitude",
				        		latitude));
				        nameValuePairs.add(new BasicNameValuePair("altiutde",
				        		altitude));
				        nameValuePairs.add(new BasicNameValuePair("time",
				        		time));
				        post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
				 
				        Log.d("LocationService", MessageFormat.format("Sending location lat:{0} long:{1} alt:{2} time:{3}", longitude, latitude, altitude, time));
				        // Query the server and store the user's ID
				        response = httpClient.execute(post);
					} catch (UnsupportedEncodingException e) {
					} catch (ClientProtocolException e) {
					} catch (IOException e) {
					}
					try {
						System.gc();
						Log.d("LocationService", "Sleeping!!");
						Thread.sleep(4000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}while(!done);
			}
		});
		
	}
	
	private void setLocationProperties(Location location){
		Log.d("LocationService", "Recieving GPS coordinates");
		
		longitude = "" + location.getLongitude();
		latitude = "" + location.getLatitude();
		altitude = "" + location.getAltitude();
		time = simpleDateFormat.format(new Date());
	}
}
